package ai.peanut.one.common.redis;


import ai.peanut.one.common.redis.lock.DistributedLocker;
import ai.peanut.one.common.redis.lock.RedissonDistributedLocker;
import ai.peanut.one.common.redis.lock.RedissonLockUtil;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.Codec;
import org.redisson.client.codec.StringCodec;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;


@ConditionalOnClass(Config.class)
@Component
public class RedissonAutoConfiguration {
    @Autowired
    private RedissonProperties redssonProperties;

    public RedissonAutoConfiguration() {
    }

    @Bean
    RedissonClient redissonSingle() {
        Config config = new Config();
        config.setCodec(new StringCodec());
        if (!StringUtils.isEmpty(this.redssonProperties.getCodec())) {
            try {
                config.setCodec((Codec) ClassUtils.forName(this.redssonProperties.getCodec(), ClassUtils.getDefaultClassLoader()).newInstance());
            } catch (Exception var3) {
                var3.printStackTrace();
            }
        }

        SingleServerConfig serverConfig = (SingleServerConfig)((SingleServerConfig)((SingleServerConfig)((SingleServerConfig)((SingleServerConfig)((SingleServerConfig)((SingleServerConfig)((SingleServerConfig)((SingleServerConfig)((SingleServerConfig)config.useSingleServer().setAddress(this.redssonProperties.getAddress()).setTimeout(this.redssonProperties.getTimeout())).setConnectionPoolSize(this.redssonProperties.getConnectionPoolSize()).setConnectionMinimumIdleSize(this.redssonProperties.getConnectionMinimumIdleSize()).setConnectionMinimumIdleSize(this.redssonProperties.getConnectionMinimumIdleSize()).setConnectionPoolSize(this.redssonProperties.getConnectionPoolSize()).setDatabase(this.redssonProperties.getDatabase()).setDnsMonitoringInterval((long)this.redssonProperties.getDnsMonitoringInterval()).setSubscriptionConnectionMinimumIdleSize(this.redssonProperties.getSubscriptionConnectionMinimumIdleSize()).setSubscriptionConnectionPoolSize(this.redssonProperties.getSubscriptionConnectionPoolSize()).setSubscriptionsPerConnection(this.redssonProperties.getSubscriptionsPerConnection())).setClientName(this.redssonProperties.getClientName())).setRetryAttempts(this.redssonProperties.getRetryAttempts())).setRetryInterval(this.redssonProperties.getRetryInterval())).setTimeout(this.redssonProperties.getTimeout())).setConnectTimeout(this.redssonProperties.getConnectTimeout())).setIdleConnectionTimeout(this.redssonProperties.getIdleConnectionTimeout())).setPingTimeout(this.redssonProperties.getPingTimeout())).setPassword(this.redssonProperties.getPassword());
        if (!StringUtils.isEmpty(this.redssonProperties.getPassword())) {
            serverConfig.setPassword(this.redssonProperties.getPassword());
        }

        return Redisson.create(config);
    }

    @Bean
    DistributedLocker distributedLocker(RedissonClient redissonClient) {
        DistributedLocker locker = new RedissonDistributedLocker();
        locker.setRedissonClient(redissonClient);
        RedissonLockUtil.setLocker(locker);
        return locker;
    }

    @Bean(
            name = {"mapperObject"}
    )
    public ObjectMapper getObjectMapper() {
        ObjectMapper om = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        om.registerModule(javaTimeModule);
        om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        return om;
    }
}
